//
// Created by johnpank on 13.01.24.
//

#ifndef FSM_TEST_FSM_H
#define FSM_TEST_FSM_H


#include <stdio.h>
#include <stdlib.h>

void test();
void cls();

/*
//global variables
int temp = 0;
int speed = 0;
char c=' ';
*/


//states
typedef enum {
    ST_STOP,
    ST_SET_TEMP,
    ST_TEMP_UP,
    ST_TEMP_DOWN,
    ST_SET_MOTOR_SPEED,
    ST_MOTOR_SPEED_UP,
    ST_MOTOR_SPEED_DOWN,
    ST_ASK_START_NO,
    ST_ASK_START_YES,
    ST_START,
    ST_MAX,
}state_type;

//events
typedef enum {
    EV_NONE,
    EV_ENC_PRESSED,
    EV_ENC_UP,
    EV_ENC_DOWN,
    EV_MAX,
} event_type;


//type pointer to func
//typedef void *(*STATE_FUNC_PTR_t)();
typedef state_type (*pfEventHandler)(void);  //handler must return state

//typedef of 2d array
typedef state_type (*const afEventHandler[ST_MAX][EV_MAX])(void);

//prototypes state-handle function
state_type stop_handler(void);
state_type set_temp_handler(void);
state_type temp_up_handler(void);
state_type temp_down_handler(void);
state_type set_motor_speed_handler(void);
state_type motor_speed_up_handler(void);
state_type motor_speed_down_handler(void);
state_type ask_start_no_handler(void);
state_type ask_start_yes_handler(void);
state_type start_handler(void);

// Table to define valid states and event of finite state machine
static afEventHandler StateMachine =
        {
                [ST_STOP] [EV_NONE]= stop_handler,
                [ST_STOP] [EV_ENC_PRESSED]= set_temp_handler,
                [ST_SET_TEMP] [EV_ENC_UP]= temp_up_handler,
                [ST_SET_TEMP] [EV_ENC_DOWN]= temp_down_handler,
                [ST_SET_TEMP] [EV_ENC_PRESSED]= set_motor_speed_handler,
                [ST_SET_TEMP] [EV_NONE]= set_temp_handler,
                [ST_TEMP_UP] [EV_NONE]= set_temp_handler,
                [ST_TEMP_DOWN] [EV_NONE]= set_temp_handler,
                [ST_SET_MOTOR_SPEED] [EV_ENC_UP]= motor_speed_up_handler,
                [ST_SET_MOTOR_SPEED] [EV_ENC_DOWN]= motor_speed_down_handler,
                [ST_SET_MOTOR_SPEED] [EV_ENC_PRESSED]= ask_start_no_handler,
                [ST_SET_MOTOR_SPEED] [EV_NONE]= set_motor_speed_handler,
                [ST_MOTOR_SPEED_UP] [EV_NONE] = set_motor_speed_handler,
                [ST_MOTOR_SPEED_DOWN] [EV_NONE] = set_motor_speed_handler,
                [ST_ASK_START_NO] [EV_ENC_UP]= ask_start_yes_handler,
                [ST_ASK_START_NO] [EV_ENC_DOWN]= ask_start_no_handler,
                [ST_ASK_START_NO] [EV_ENC_PRESSED]= ask_start_no_handler,
                [ST_ASK_START_YES] [EV_ENC_PRESSED]= start_handler,
                [ST_ASK_START_YES] [EV_ENC_DOWN]= ask_start_no_handler,
                [ST_ASK_START_YES] [EV_ENC_UP]= ask_start_yes_handler,
        };

/*
//transition table
void (*const transition_table[ST_MAX][EV_MAX])(void) = {
    [ST_STOP]               [EV_ENC_PRESSED]    = set_temp(),
    [ST_SET_TEMP]           [EV_ENC_PRESSED]    = set_motor_speed(),
    [ST_SET_MOTOR_SPEED]    [EV_ENC_PRESSED]    = ask_start_no(),
    [ST_ASK_START_NO]       [EV_ENC_UP]         = ask_start_yes(),
    [ST_ASK_START_YES]      [EV_ENC_PRESSED]    = start(),
};
*/

/*
// Table to define valid states and event of finite state machine
static afEventHandler StateMachine =
        {
                [ST_STOP] ={[EV_NONE]= stop_handler },
                [ST_STOP] ={[EV_ENC_PRESSED]= set_temp_handler },
                [ST_SET_TEMP] ={[EV_ENC_UP]= temp_up_handler },
                [ST_SET_TEMP] ={[EV_ENC_DOWN]= temp_down_handler },
                [ST_SET_TEMP] ={[EV_ENC_PRESSED]= set_motor_speed_handler },
                [ST_SET_TEMP] ={[EV_NONE]= set_temp_handler },
                [ST_SET_MOTOR_SPEED] ={[EV_ENC_UP]= motor_speed_up_handler },
                [ST_SET_MOTOR_SPEED] ={[EV_ENC_DOWN]= motor_speed_down_handler },
                [ST_SET_MOTOR_SPEED] ={[EV_ENC_PRESSED]= ask_start_no_handler },
                [ST_ASK_START_NO] ={[EV_ENC_UP]= ask_start_yes_handler },
                [ST_ASK_START_NO] ={[EV_ENC_DOWN]= ask_start_no_handler },
                [ST_ASK_START_NO] ={[EV_ENC_PRESSED]= ask_start_no_handler },
                [ST_ASK_START_YES] ={[EV_ENC_PRESSED]= start_handler },
                [ST_ASK_START_YES] ={[EV_ENC_DOWN]= ask_start_no_handler },
        };
*/



#endif //FSM_TEST_FSM_H
